﻿using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace Common.Extensions
{
    /// <summary>
    /// Object的扩展方法
    /// </summary>
    public static class ObjectExtensions
    {
        #region Json
        /// <summary>
        /// Object转Json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJson(this object? obj)
        {
            return JsonConvert.SerializeObject(obj);
        }
        /// <summary>
        /// Object转Json格式符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToJsonFormat(this object? value)
        {
            var settings = new JsonSerializerSettings()
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                DateFormatString = "yyyy-MM-ddTHH:mm:ss"
            };
            return JsonConvert.SerializeObject(value, settings);
        }
        /// <summary>
        /// Json字符串转Object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T? ToObject<T>(this string value)
        {
            return JsonConvert.DeserializeObject<T>(value);
        }
        #endregion
        /// <summary>
        /// 复制属性到目标
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TDestination"></typeparam>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public static void CopyPropertiesTo<TSource, TDestination>(this TSource? source, TDestination? destination)
            where TSource : class
            where TDestination : class
        {
            if (source == null || destination == null)
            {
                throw new ArgumentNullException("SourceOrDestination", "源或目标为空");
            }
            var sourceProperties = typeof(TSource).GetProperties();
            var destinationProperties = typeof(TDestination).GetProperties();
            foreach (var sourceProp in sourceProperties)
            {
                foreach (var destProp in destinationProperties)
                {
                    // 判断属性名是否相同, 类型是否相同, 目标属性是否可写
                    if (destProp.Name == sourceProp.Name && destProp.PropertyType == sourceProp.PropertyType && destProp.CanWrite)
                    {
                        destProp.SetValue(destination, sourceProp.GetValue(source));
                        break;
                    }
                }
            }
        }
    }
}
